﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.IO;
using WyoCodeTools.Classes;
using EnvDTE;
using WyoCode.WyoApp_VSTools;

public class VSProjectFile
{

    public XElement ProjectXML { get; set; }
    public string ProjectLoc { get; set; }

    public List<VSEdmxFile> EDMXFiles { get; private set; }
    public XNamespace _NS = "http://schemas.microsoft.com/developer/msbuild/2003";

    public string ConnectionString { get; set; }

    public List<string> Files = new List<string>();
    public List<VSConfigFile> Configs = new List<VSConfigFile>();
    public EnvDTE.Project DTE_Project;

    public string Name { get { return DTE_Project.Name; } }

    public VSProjectFile(string fileloc)
    {
        ProjectXML = XElement.Load(fileloc);
        ProjectLoc = fileloc;
        EDMXFiles = new List<VSEdmxFile>();
        GetEntities();
        Init();
    }

    public VSProjectFile(EnvDTE.Project item)
    {
        // TODO: Complete member initialization
        this.DTE_Project = item;
        ProjectXML = XElement.Load(DTE_Project.FullName);
        ProjectLoc = DTE_Project.FullName;
        EDMXFiles = new List<VSEdmxFile>();
        GetEntities();
        Init();
        
    }


    public List<VSSLProject> GetSilverlightProjects()
    {
        //<SilverlightApplicationList>
        var ol = new List<VSSLProject>();
        XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
        foreach (var e in ProjectXML.Descendants(ns + "SilverlightApplicationList"))
        {

            ol.Add(new VSSLProject(e.Value, DTE_Project));
        }

        return ol;
    }

    private void Init()
    {

        foreach (ProjectItem item in DTE_Project.ProjectItems)
        {
            if (Path.GetExtension(item.Name) == ".config")
            {


                this.Configs.Add(new VSConfigFile(new Uri(new Uri(ProjectLoc), item.Name).AbsolutePath.Replace("%20", " ")));
            }
        }




        //XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
        //foreach (var e in ProjectXML.Descendants(ns + "Compile"))
        //{
        //    Files.Add(e.Attribute("Include").Value);

        //}
        //foreach (var e in ProjectXML.Descendants(ns + "Content"))
        //{
        //    Files.Add(e.Attribute("Include").Value);
        //    if (Path.GetExtension(e.Attribute("Include").Value) == ".config")
        //    {
        //        this.Configs.Add( new VSConfigFile( new Uri( new Uri(ProjectLoc), e.Attribute("Include").Value).AbsolutePath.Replace("%20", " ")));
        //    }
        //}
        //foreach (var e in ProjectXML.Descendants(ns + "None"))
        //{
        //    //Files.Add(e.Attribute("Include").Value);
        //    if (Path.GetExtension(e.Attribute("Include").Value) == ".config")
        //    {
        //        this.Configs.Add(new VSConfigFile(new Uri(new Uri(ProjectLoc), e.Attribute("Include").Value).AbsolutePath.Replace("%20", " ")));
        //    }
        //}

    }

    public Dictionary<string, string> ConnectionStrings
    {
        get
        {
            Dictionary<string, string> outd = new Dictionary<string, string>();
            foreach (var cfg in Configs)
            {
                foreach (var cs in cfg.ConnectionStrings)
                {
                    outd.Add(cs.Key, cs.Value);
                }
            }
            return outd;

        }


    }

    public void GetEntities()
    {
        //     <ItemGroup>
        //  <EntityDeploy Include="Support.edmx">
        //    <Generator>EntityModelCodeGenerator</Generator>
        //    <LastGenOutput>Support.Designer.cs</LastGenOutput>
        //  </EntityDeploy>
        //</ItemGroup>

        //xmlns="http://schemas.microsoft.com/developer/msbuild/2003"

        XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";

        var entities = this.ProjectXML.Descendants(ns + "EntityDeploy");
        foreach (var ex in entities)
        {

            EDMXFiles.Add(new VSEdmxFile(new Uri(new Uri(ProjectLoc), ex.Attribute("Include").Value).AbsoluteUri));
        }


    }


    public void AddCompileFile(string filerelative, XElement attribXML)
    {
        //<Compile Include="Properties\AssemblyInfo.cs" />
        // find compile ItemGroup contatiner


        var compileItemGroup = ProjectXML.Descendants(_NS + "ItemGroup").First(ig => ig.Descendants(_NS + "Compile").Count() > 0);
        if (compileItemGroup.Descendants(_NS + "Compile").Count(e => e.Attribute("Include").Value == filerelative) == 0)
        {
            if (attribXML != null)
            {
                compileItemGroup.Add(new XElement(_NS + "Compile", new XAttribute("Include", filerelative), attribXML.Descendants()));
            }
            else
            {
                compileItemGroup.Add(new XElement(_NS + "Compile", new XAttribute("Include", filerelative)));
            }
            ProjectXML.Save(this.ProjectLoc);
        }


    }

    public void WriteCodeFile(string code, string filerelative, XElement attribXML)
    {
        AddCompileFile(filerelative, attribXML);
        File.WriteAllText(Path.Combine(new FileInfo(this.ProjectLoc).Directory.FullName, filerelative), code);
    }


    public void AddContentFile(string filerelative, XElement attribXML)
    {
        //<Compile Include="Properties\AssemblyInfo.cs" />
        // find compile ItemGroup contatiner
        var contentItemGroup = ProjectXML.Descendants(_NS + "ItemGroup").First(ig => ig.Descendants(_NS + "Content").Count() > 0);
        if (contentItemGroup.Descendants(_NS + "Content").Count(e => e.Attribute("Include").Value == filerelative) == 0)
        {
            if (attribXML != null)
            {
                contentItemGroup.Add(new XElement(_NS + "Content", new XAttribute("Include", filerelative), attribXML.Descendants()));
            }
            else
            {
                contentItemGroup.Add(new XElement(_NS + "Content", new XAttribute("Include", filerelative)));
            }
            ProjectXML.Save(this.ProjectLoc);
        }


    }

    public void AddRefrence(string refrence, XElement attribXML)
    {
        //<Compile Include="Properties\AssemblyInfo.cs" />
        // find compile ItemGroup contatiner
        var contentItemGroup = ProjectXML.Descendants(_NS + "ItemGroup").First(ig => ig.Descendants(_NS + "Reference").Count() > 0);
        if (contentItemGroup.Descendants(_NS + "Reference").Count(e => e.Attribute("Include").Value == refrence) == 0)
        {
            if (attribXML != null)
            {
                contentItemGroup.Add(new XElement(_NS + "Reference", new XAttribute("Include", refrence), attribXML.Descendants()));
            }
            else
            {
                contentItemGroup.Add(new XElement(_NS + "Reference", new XAttribute("Include", refrence)));
            }
            ProjectXML.Save(this.ProjectLoc);
        }


    }

    public void WriteContentFile(string filetext, string filerelative, XElement attribXML)
    {
        AddContentFile(filerelative, attribXML);
        File.WriteAllText(Path.Combine(new FileInfo(this.ProjectLoc).Directory.FullName, filerelative), filetext);
    }

    public bool CodeFileExists(string filerelative)
    {
        var compileItemGroup = ProjectXML.Descendants(_NS + "ItemGroup").First(ig => ig.Descendants(_NS + "Compile").Count() > 0);
        if (compileItemGroup.Descendants(_NS + "Compile").Count(e => e.Attribute("Include").Value == filerelative) > 0)
        {
            return true;
        }
        return false;
    }

    public bool ContentFileExists(string filerelative)
    {
        var compileItemGroup = ProjectXML.Descendants(_NS + "ItemGroup").First(ig => ig.Descendants(_NS + "Content").Count() > 0);
        if (compileItemGroup.Descendants(_NS + "Content").Count(e => e.Attribute("Include").Value == filerelative) > 0)
        {
            return true;
        }
        return false;
    }


    //RootNamespace
    public string Namespace
    {
        get
        {
            return ProjectXML.Descendants(_NS + "RootNamespace").First().Value;
        }
    }

    public string WebDevPort
    {
        get
        {
            var webele = ProjectXML.Descendants(_NS + "WebProjectProperties").First();
            return webele.Descendants(_NS + "DevelopmentServerPort").First().Value;
        }
    }

    public string WebDevDir
    {
        get
        {
            var webele = ProjectXML.Descendants(_NS + "WebProjectProperties").First();
            return webele.Descendants(_NS + "DevelopmentServerVPath").First().Value;
        }
    }

    public string WebURL
    {
        get
        {
        //    <WebProjectProperties>
        //  <UseIIS>False</UseIIS>
        //  <AutoAssignPort>True</AutoAssignPort>
        //  <DevelopmentServerPort>12386</DevelopmentServerPort>
        //  <DevelopmentServerVPath>/</DevelopmentServerVPath>
        //  <IISUrl></IISUrl>
        //  <NTLMAuthentication>False</NTLMAuthentication>
        //  <UseCustomServer>False</UseCustomServer>
        //  <CustomServerUrl></CustomServerUrl>
        //  <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
        //</WebProjectProperties>


            var webele = ProjectXML.Descendants(_NS + "WebProjectProperties").First();
            if (webele.Descendants(_NS + "UseIIS").First().Value == "True")
            {
                return webele.Descendants(_NS + "IISUrl").First().Value;
            }
            else if (webele.Descendants(_NS + "UseCustomServer").First().Value == "True")
            {
                return webele.Descendants(_NS + "CustomServerUrl").First().Value;
            }
            else
            {
                return "http://localhost:" + webele.Descendants(_NS + "DevelopmentServerPort").First().Value + webele.Descendants(_NS + "DevelopmentServerVPath").First().Value;
            }

        }
    }
}


